package com.lcredu.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 黎长容
 * @date 2025-07-14 19:58
 */
public class VehicleProxyProvider {
    //设置一个将来要运行的对象，只要是实现了 Vehicle 接口的就 ok
    private Vehicle target_vehicle;

    public VehicleProxyProvider(Vehicle target_vehicle) {
        this.target_vehicle = target_vehicle;
    }

    //编写方法，返回一个 Vehicle 的代理对象
    public Vehicle getProxy() {

        //1.得到类的加载器
        ClassLoader classLoader = target_vehicle.getClass().getClassLoader();

        //2.得到要代理对象的接口信息,底层是通过接口进行调用
        Class<?>[] interfaces = target_vehicle.getClass().getInterfaces();

        /**
         * Object proxy : 代理对象
         * method : 通过代理对象调用方法时的那个方法
         * Object[] args : 调用代理对象run方法的时候传入的参数
         * return : 代理对象.run(xx)执行后的结果
         *
         * public interface InvocationHandler {
         *    public Object invoke(Object proxy, Method method, Object[] args)
         *         throws Throwable;
         * }
         *
         * invoke: 将来我们调用target_vehicle的方法时会调用的
         *
         */
        //3.得到调用处理器
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("交通工具开始运行了...");
                //这是我们的反射基础
                //method : public abstract void com.lcredu.proxy.Vehicle.run()  代理对象的run
                //target_vehicle : Ship
                //args : 参数
                //result : 返回结果
                Object result = method.invoke(target_vehicle, args);
                System.out.println("交通工具停止运行了...");
                return result;
            }
        };


        /**
         *     public static Object newProxyInstance(ClassLoader loader,
         *                                           Class<?>[] interfaces,
         *                                           InvocationHandler h)
         *    Proxy.newProxyInstance() : 可以返回一个代理对象                                       
         *    ClassLoader loader : 类加载器
         *    Class<?>[] interfaces : 真正要代理的对象的接口信息
         *    InvocationHandler h : 调用处理器/对象 有一个非常重要的方法invoke
         */
        Vehicle vehicle = (Vehicle) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return vehicle;
    }
}
